ServerEvents.recipes((event) => {
    let RegisteredFormula = (perenergy, input_items, output_items) => {
        event.recipes.custommachinery.custom_machine("eou:laser_carver/controller", 200)
            .requireStructure([[
                "ACA",
                "DAB",
                "AmA",
            ], [
                "AAA",
                "A A",
                "AAA",
            ], [
                "AAA",
                "AEA",
                "AAA",
            ]], {
                "A": "eou:laser_carver_shell",
                "B": "eou:laser_carver/stress_port",
                "C": "eou:laser_carver/exportation_port",
                "D": "eou:laser_carver/power_port",
                "E": "eou:laser_carver/feed_port"
            })
            .requireFunctionToStart((ctx) => {
                let level = ctx.block.minecraftLevel
                let pos = ctx.block.getPos()
                let facing = ctx.getBlock().getProperties().get("facing")
                //控制器其他机器相对坐标
                let ports_pos = { power: [-1, 0, -1], exportation: [0, 0, -2], feed: [0, 2, -1], stress: [1, 0, -1] }
                let ports = global.getothermachine(pos, ports_pos, facing, level)
                if (ports["stress"].data.supply == 0) {
                    return Result.error("understress")
                }
                for (let i in input_items) {
                    let sum = 0, f = 0;
                    for (let j = 0; j < 27; j++) {
                        if (ports["feed"].getItemStored("slot" + j).getId() == input_items[i].name) {
                            sum += ports["feed"].getItemStored("slot" + j).count;
                            if (sum >= input_items[i].count) {
                                f = 1;
                                break;
                            }
                        }
                    }
                    if (f == 0) return Result.error("underinput")
                }
                for (let i in input_items) {
                    let sum = input_items[i].count;
                    for (let j = 0; j < 27; j++) {
                        if (ports["feed"].getItemStored("slot" + j).getId() == input_items[i].name) {
                            let c = ports["feed"].getItemStored("slot" + j).count;
                            if (c > sum) c = sum;
                            ports["feed"].removeItemFromSlot("slot" + j, c, false);
                            sum -= c;
                            if (sum == 0) {
                                break;
                            }
                        }
                    }
                }
                return Result.success()
            })
            .requireFunctionEachTick((ctx) => {
                let level = ctx.block.minecraftLevel
                let pos = ctx.block.getPos()
                let facing = ctx.getBlock().getProperties().get("facing")
                //控制器其他机器相对坐标
                let ports_pos = { power: [-1, 0, -1], exportation: [0, 0, -2], feed: [0, 2, -1], stress: [1, 0, -1] }
                let ports = global.getothermachine(pos, ports_pos, facing, level)
                if (ports["power"].getEnergyStored() < perenergy) {
                    return Result.error("underpower")
                }
                if (ports["stress"].data.supply == 0) {
                    return Result.error("understress")
                }
                ports["stress"].data.work = 1;
                ports["power"].removeEnergy(perenergy, false)
                return Result.success()
            })
            .requireFunctionOnEnd((ctx) => {
                let level = ctx.block.minecraftLevel
                let pos = ctx.block.getPos()
                let facing = ctx.getBlock().getProperties().get("facing")
                //控制器其他机器相对坐标
                let ports_pos = { power: [-1, 0, -1], exportation: [0, 0, -2], feed: [0, 2, -1], stress: [1, 0, -1] }
                let ports = global.getothermachine(pos, ports_pos, facing, level)
                for (let i in output_items) {
                    let sum = output_items[i].count;
                    for (let j = 0; j < 4; j++) {
                        if (ports["exportation"].getItemStored("slot" + j).getId() == output_items[i].name
                            || ports["exportation"].getItemStored("slot" + j).getId() == "minecraft:air") {
                            let c = ports["exportation"].getItemCapacity("slot" + j) - ports["exportation"].getItemStored("slot" + j).count;
                            if (c > sum) c = sum;
                            ports["exportation"].addItemToSlot("slot" + j, Item.of(output_items[i].name, c), false)
                            sum -= c;
                            if (sum == 0) {
                                break;
                            }
                        }
                    }
                }
                ports["stress"].data.work = 0;
                return Result.success()
            })
            .resetOnError()
            .jei()
            .priority(10000 - perenergy)
            .requireItem(input_items.length >= 1 ? Item.of(input_items[0].name, input_items[0].count) : Item.empty)
            .requireItem(input_items.length >= 2 ? Item.of(input_items[1].name, input_items[1].count) : Item.empty)
            .requireItem(input_items.length >= 3 ? Item.of(input_items[2].name, input_items[2].count) : Item.empty)
            .requireItem(input_items.length >= 4 ? Item.of(input_items[3].name, input_items[3].count) : Item.empty)
            .requireItem(input_items.length >= 5 ? Item.of(input_items[4].name, input_items[4].count) : Item.empty)
            .requireItem(input_items.length >= 6 ? Item.of(input_items[5].name, input_items[5].count) : Item.empty)
            .requireItem(input_items.length >= 7 ? Item.of(input_items[6].name, input_items[6].count) : Item.empty)
            .requireItem(input_items.length >= 8 ? Item.of(input_items[7].name, input_items[7].count) : Item.empty)
            .requireItem(input_items.length >= 9 ? Item.of(input_items[8].name, input_items[8].count) : Item.empty)
            .requireItem(input_items.length >= 10 ? Item.of(input_items[9].name, input_items[9].count) : Item.empty)
            .requireItem(input_items.length >= 11 ? Item.of(input_items[10].name, input_items[10].count) : Item.empty)
            .requireItem(input_items.length >= 12 ? Item.of(input_items[11].name, input_items[11].count) : Item.empty)
            .requireItem(input_items.length >= 13 ? Item.of(input_items[12].name, input_items[12].count) : Item.empty)
            .requireItem(input_items.length >= 14 ? Item.of(input_items[13].name, input_items[13].count) : Item.empty)
            .requireItem(input_items.length >= 15 ? Item.of(input_items[14].name, input_items[14].count) : Item.empty)
            .requireItem(input_items.length >= 16 ? Item.of(input_items[15].name, input_items[15].count) : Item.empty)
            .requireItem(input_items.length >= 17 ? Item.of(input_items[16].name, input_items[16].count) : Item.empty)
            .requireItem(input_items.length >= 18 ? Item.of(input_items[17].name, input_items[17].count) : Item.empty)
            .requireItem(input_items.length >= 19 ? Item.of(input_items[18].name, input_items[18].count) : Item.empty)
            .requireItem(input_items.length >= 20 ? Item.of(input_items[19].name, input_items[19].count) : Item.empty)
            .requireItem(input_items.length >= 21 ? Item.of(input_items[20].name, input_items[20].count) : Item.empty)
            .requireItem(input_items.length >= 22 ? Item.of(input_items[21].name, input_items[21].count) : Item.empty)
            .requireItem(input_items.length >= 23 ? Item.of(input_items[22].name, input_items[22].count) : Item.empty)
            .requireItem(input_items.length >= 24 ? Item.of(input_items[23].name, input_items[23].count) : Item.empty)
            .requireItem(input_items.length >= 25 ? Item.of(input_items[24].name, input_items[24].count) : Item.empty)
            .requireItem(input_items.length >= 26 ? Item.of(input_items[25].name, input_items[25].count) : Item.empty)
            .requireItem(input_items.length >= 27 ? Item.of(input_items[26].name, input_items[26].count) : Item.empty)
            .produceItem(output_items.length >= 1 ? Item.of(output_items[0].name, output_items[0].count) : Item.empty)
            .produceItem(output_items.length >= 2 ? Item.of(output_items[1].name, output_items[1].count) : Item.empty)
            .produceItem(output_items.length >= 3 ? Item.of(output_items[2].name, output_items[2].count) : Item.empty)
            .produceItem(output_items.length >= 4 ? Item.of(output_items[3].name, output_items[3].count) : Item.empty)
            .requireEnergyPerTick(perenergy)
            .requireSU(256, 16384)
    }
    let base = [
        { name: "eou:standard_silicon_wafer", count: 1 },
        { name: "eou:laser_crystal", count: 1 },
        { name: "eou:energy_exciter", count: 1 },
        { name: "eou:focusing_negative", count: 1 }
    ]
    let out = [
        { name: "pneumaticcraft:transistor", count: 1 }
    ]
    let change = [[
        { name: 'minecraft:diamond_block', count: 4 },
        { name: 'minecraft:obsidian', count: 64 },
        { name: 'minecraft:iron_block', count: 8 },
        { name: 'minecraft:copper_block', count: 8 },
        { name: 'create:sturdy_sheet', count: 16 },
        { name: 'create:precision_mechanism', count: 64 }
    ], [
        { name: 'minecraft:redstone_block', count: 16 },
        { name: 'createindustry:plastic_sheet', count: 16 },
        { name: 'minecraft:gold_block', count: 8 },
        { name: 'minecraft:blue_ice', count: 128 },
        { name: 'create:zinc_block', count: 16 },
        { name: 'mekanism:block_tin', count: 16 },
        { name: 'create:precision_mechanism', count: 64 }
    ], [
        { name: 'minecraft:quartz_block', count: 16 },
        { name: 'createindustry:plastic_sheet', count: 16 },
        { name: 'minecraft:slime_block', count: 64 },
        { name: 'createaddition:electrum_ingot', count: 128 },
        { name: 'create:precision_mechanism', count: 64 }
    ]]
    //注册晶体管配方
    for (let i = 0; i < 8; i++) {
        let a = [];
        let num = 100;
        a.push(base[0])
        if ((i & 1) == 1) {
            num += 50;
            for (let j = 0; j < change[0].length; j++) {
                a.push({ name: change[0][j].name, count: change[0][j].count });
            }
        } else {
            a.push(base[1])
        }
        if ((i & 2) == 2) {
            num += 50;
            for (let j = 0; j < change[1].length; j++) {
                let f = 0;
                for (let k = 0; k < a.length; k++) {
                    if (a[k].name == change[1][j].name) {
                        a[k].count += change[1][j].count
                        f = 1;
                        break;
                    }
                }
                if (f == 0) a.push({ name: change[1][j].name, count: change[1][j].count });
            }
        } else {
            a.push(base[2])
        }
        if ((i & 4) == 4) {
            num += 50;
            for (let j = 0; j < change[2].length; j++) {
                let f = 0;
                for (let k = 0; k < a.length; k++) {
                    if (a[k].name == change[2][j].name) {
                        a[k].count += change[2][j].count
                        f = 1;
                        break;
                    }
                }
                if (f == 0) a.push({ name: change[2][j].name, count: change[2][j].count });
            }
        } else {
            a.push(base[3])
        }
        RegisteredFormula(num, a, out)
    }
    //注册模块化机器核心
    RegisteredFormula(1000, [
        { name: "pneumaticcraft:transistor", count: 1 },
        { name: 'minecraft:diamond_block', count: 1 },
        { name: 'minecraft:redstone_block', count: 1 }
    ], [
        { name: 'eou:modular_mechanical_core', count: 1 }
    ])

    event.remove({ id: 'pneumaticcraft:pressure_chamber/compressed_iron_ingot' })
    event.remove({ id: 'pneumaticcraft:explosion_crafting/compressed_iron_ingot' })
    RegisteredFormula(500, [//压缩铁锭
        { name: 'minecraft:iron_ingot', count: 1 },
        { name: 'pneumaticcraft:transistor', count: 1 }
    ], [
        { name: 'pneumaticcraft:ingot_iron_compressed', count: 1 }
    ])

    event.remove({ id: 'pneumaticcraft:pressure_chamber/compressed_iron_block' })
    event.remove({ id: 'pneumaticcraft:explosion_crafting/compressed_iron_block' })
    RegisteredFormula(4000, [//压缩铁块
        { name: 'pneumaticcraft:transistor', count: 5 },
        { name: 'minecraft:iron_block', count: 1 },
        { name: 'eou:laser_crystal', count: 1 },
        { name: 'eou:energy_exciter', count: 1 },
        { name: 'eou:focusing_negative', count: 1 }
    ], [
        { name: 'pneumaticcraft:compressed_iron_block', count: 1 }
    ])
})